using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Domain.Services;
using Volo.Abp.Uow;
using Matrix.Notification.Domain.Notifications;
using Matrix.Notification.Domain.Shared.Notifications;

namespace Matrix.Notification.Application.Logging
{
    /// <summary>
    /// 通知日志扩展
    /// </summary>
    public static class NotificationLoggerExtensions
    {
        /// <summary>
        /// 记录通知创建日志
        /// </summary>
        public static IDisposable? LogNotificationCreating(
            this ILogger logger,
            Guid notificationId,
            string title,
            NotificationType type,
            NotificationChannel channel,
            Guid? recipientId = null)
        {
            return logger.BeginScope(new Dictionary<string, object>
            {
                ["NotificationId"] = notificationId,
                ["Action"] = "Creating",
                ["Title"] = title,
                ["Type"] = type.ToString(),
                ["Channel"] = channel.ToString(),
                ["RecipientId"] = recipientId,
                ["Timestamp"] = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 记录通知创建成功日志
        /// </summary>
        public static void LogNotificationCreated(
            this ILogger logger,
            Notification notification,
            TimeSpan duration)
        {
            logger.LogInformation(
                "通知创建成功: Id={Id}, Title={Title}, Type={Type}, Channel={Channel}, " +
                "RecipientId={RecipientId}, Duration={Duration}ms",
                notification.Id,
                notification.Title,
                notification.Type,
                notification.Channel,
                notification.RecipientId,
                duration.TotalMilliseconds);
        }

        /// <summary>
        /// 记录通知创建失败日志
        /// </summary>
        public static void LogNotificationCreationFailed(
            this ILogger logger,
            Exception exception,
            string title,
            NotificationType type,
            NotificationChannel channel,
            Guid? recipientId = null,
            TimeSpan duration = default)
        {
            logger.LogError(exception,
                "通知创建失败: Title={Title}, Type={Type}, Channel={Channel}, " +
                "RecipientId={RecipientId}, Duration={Duration}ms, Error={Error}",
                title,
                type,
                channel,
                recipientId,
                duration.TotalMilliseconds,
                exception.Message);
        }

        /// <summary>
        /// 记录通知发送日志
        /// </summary>
        public static void LogNotificationSending(
            this ILogger logger,
            Guid notificationId,
            NotificationChannel channel,
            string? recipient = null)
        {
            logger.LogInformation(
                "开始发送通知: Id={Id}, Channel={Channel}, Recipient={Recipient}",
                notificationId,
                channel,
                recipient);
        }

        /// <summary>
        /// 记录通知发送成功日志
        /// </summary>
        public static void LogNotificationSent(
            this ILogger logger,
            Guid notificationId,
            NotificationChannel channel,
            string? externalId = null,
            TimeSpan duration = default)
        {
            logger.LogInformation(
                "通知发送成功: Id={Id}, Channel={Channel}, ExternalId={ExternalId}, Duration={Duration}ms",
                notificationId,
                channel,
                externalId,
                duration.TotalMilliseconds);
        }

        /// <summary>
        /// 记录通知发送失败日志
        /// </summary>
        public static void LogNotificationSendFailed(
            this ILogger logger,
            Guid notificationId,
            NotificationChannel channel,
            string failureReason,
            int retryCount,
            TimeSpan duration = default)
        {
            logger.LogWarning(
                "通知发送失败: Id={Id}, Channel={Channel}, FailureReason={FailureReason}, " +
                "RetryCount={RetryCount}, Duration={Duration}ms",
                notificationId,
                channel,
                failureReason,
                retryCount,
                duration.TotalMilliseconds);
        }

        /// <summary>
        /// 记录通知送达日志
        /// </summary>
        public static void LogNotificationDelivered(
            this ILogger logger,
            Guid notificationId,
            NotificationChannel channel,
            TimeSpan deliveryTime)
        {
            logger.LogInformation(
                "通知已送达: Id={Id}, Channel={Channel}, DeliveryTime={Duration}ms",
                notificationId,
                channel,
                deliveryTime.TotalMilliseconds);
        }

        /// <summary>
        /// 记录通知读取日志
        /// </summary>
        public static void LogNotificationRead(
            this ILogger logger,
            Guid notificationId,
            Guid userId,
            TimeSpan readTime)
        {
            logger.LogInformation(
                "通知已读取: Id={Id}, UserId={UserId}, ReadTime={Duration}ms",
                notificationId,
                userId,
                readTime.TotalMilliseconds);
        }

        /// <summary>
        /// 记录批次发送开始日志
        /// </summary>
        public static void LogBatchSendingStarted(
            this ILogger logger,
            Guid batchId,
            string batchName,
            int totalRecipients)
        {
            logger.LogInformation(
                "开始发送通知批次: Id={Id}, Name={Name}, TotalRecipients={TotalRecipients}",
                batchId,
                batchName,
                totalRecipients);
        }

        /// <summary>
        /// 记录批次发送完成日志
        /// </summary>
        public static void LogBatchSendingCompleted(
            this ILogger logger,
            Guid batchId,
            string batchName,
            int totalRecipients,
            int sentCount,
            int deliveredCount,
            int failedCount,
            TimeSpan duration)
        {
            logger.LogInformation(
                "通知批次发送完成: Id={Id}, Name={Name}, Total={Total}, Sent={Sent}, " +
                "Delivered={Delivered}, Failed={Failed}, Duration={Duration}ms",
                batchId,
                batchName,
                totalRecipients,
                sentCount,
                deliveredCount,
                failedCount,
                duration.TotalMilliseconds);
        }

        /// <summary>
        /// 记录模板使用日志
        /// </summary>
        public static void LogTemplateUsed(
            this ILogger logger,
            Guid templateId,
            string templateName,
            NotificationChannel channel,
            TimeSpan renderTime)
        {
            logger.LogInformation(
                "模板使用: Id={Id}, Name={Name}, Channel={Channel}, RenderTime={Duration}ms",
                templateId,
                templateName,
                channel,
                renderTime.TotalMilliseconds);
        }

        /// <summary>
        /// 记录订阅变更日志
        /// </summary>
        public static void LogSubscriptionChanged(
            this ILogger logger,
            Guid userId,
            string action,
            NotificationType? type = null,
            NotificationChannel? channel = null)
        {
            logger.LogInformation(
                "用户订阅变更: UserId={UserId}, Action={Action}, Type={Type}, Channel={Channel}",
                userId,
                action,
                type?.ToString(),
                channel?.ToString());
        }

        /// <summary>
        /// 记录性能指标日志
        /// </summary>
        public static void LogPerformanceMetrics(
            this ILogger logger,
            string operation,
            TimeSpan duration,
            int processedCount,
            bool success = true,
            Dictionary<string, object>? additionalMetrics = null)
        {
            var metrics = new Dictionary<string, object>
            {
                ["Operation"] = operation,
                ["Duration"] = duration.TotalMilliseconds,
                ["ProcessedCount"] = processedCount,
                ["Success"] = success,
                ["Throughput"] = processedCount > 0 ? processedCount / duration.TotalSeconds : 0,
                ["Timestamp"] = DateTime.UtcNow
            };

            if (additionalMetrics != null)
            {
                foreach (var metric in additionalMetrics)
                {
                    metrics[metric.Key] = metric.Value;
                }
            }

            var logLevel = success ? LogLevel.Information : LogLevel.Warning;
            logger.Log(logLevel,
                "性能指标: {@Metrics}",
                metrics);
        }

        /// <summary>
        /// 记录业务指标日志
        /// </summary>
        public static void LogBusinessMetrics(
            this ILogger logger,
            string metricName,
            double value,
            Dictionary<string, object>? tags = null)
        {
            var metrics = new Dictionary<string, object>
            {
                ["MetricName"] = metricName,
                ["Value"] = value,
                ["Timestamp"] = DateTime.UtcNow
            };

            if (tags != null)
            {
                foreach (var tag in tags)
                {
                    metrics[$"Tag_{tag.Key}"] = tag.Value;
                }
            }

            logger.LogInformation(
                "业务指标: {@Metrics}",
                metrics);
        }

        /// <summary>
        /// 记录错误日志
        /// </summary>
        public static void LogNotificationError(
            this ILogger logger,
            Exception exception,
            string operation,
            Guid? notificationId = null,
            Guid? userId = null,
            Dictionary<string, object>? additionalContext = null)
        {
            var context = new Dictionary<string, object>
            {
                ["Operation"] = operation,
                ["ExceptionType"] = exception.GetType().Name,
                ["ExceptionMessage"] = exception.Message,
                ["Timestamp"] = DateTime.UtcNow
            };

            if (notificationId.HasValue)
            {
                context["NotificationId"] = notificationId.Value;
            }

            if (userId.HasValue)
            {
                context["UserId"] = userId.Value;
            }

            if (additionalContext != null)
            {
                foreach (var item in additionalContext)
                {
                    context[item.Key] = item.Value;
                }
            }

            logger.LogError(exception,
                "通知服务错误: {@Context}",
                context);
        }

        /// <summary>
        /// 记录警告日志
        /// </summary>
        public static void LogNotificationWarning(
            this ILogger logger,
            string message,
            string operation,
            Guid? notificationId = null,
            Guid? userId = null,
            Dictionary<string, object>? additionalContext = null)
        {
            var context = new Dictionary<string, object>
            {
                ["Message"] = message,
                ["Operation"] = operation,
                ["Timestamp"] = DateTime.UtcNow
            };

            if (notificationId.HasValue)
            {
                context["NotificationId"] = notificationId.Value;
            }

            if (userId.HasValue)
            {
                context["UserId"] = userId.Value;
            }

            if (additionalContext != null)
            {
                foreach (var item in additionalContext)
                {
                    context[item.Key] = item.Value;
                }
            }

            logger.LogWarning(
                "通知服务警告: {@Context}",
                context);
        }
    }
}